<?php

if (! defined ( 'BASEPATH' ))
	exit ( 'No direct script access allowed' );
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------


/**
 * Javascript Class
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Javascript
 * @author		ExpressionEngine Dev Team
 * @link		http://codeigniter.com/user_guide/libraries/javascript.html
 */
class CI_Javascript {
	
	var $_javascript_location = 'js';
	
	public function __construct($params = array()) {
		$defaults = array ('js_library_driver' => 'jquery', 'autoload' => TRUE );
		
		foreach ( $defaults as $key => $val ) {
			if (isset ( $params [$key] ) && $params [$key] !== "") {
				$defaults [$key] = $params [$key];
			}
		}
		
		extract ( $defaults );
		
		$this->CI = & get_instance ();
		
		// load the requested js library
		$this->CI->load->library ( 'javascript/' . $js_library_driver, array ('autoload' => $autoload ) );
		// make js to refer to current library
		$this->js = & $this->CI->$js_library_driver;
		
		log_message ( 'debug', "Javascript Class Initialized and loaded.  Driver used: $js_library_driver" );
	}
	
	// --------------------------------------------------------------------
	// Event Code
	// --------------------------------------------------------------------
	

	/**
	 * Blur
	 *
	 * Outputs a javascript library blur event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function blur($element = 'this', $js = '') {
		return $this->js->_blur ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Change
	 *
	 * Outputs a javascript library change event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function change($element = 'this', $js = '') {
		return $this->js->_change ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Click
	 *
	 * Outputs a javascript library click event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @param	boolean	whether or not to return false
	 * @return	string
	 */
	function click($element = 'this', $js = '', $ret_false = TRUE) {
		return $this->js->_click ( $element, $js, $ret_false );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Double Click
	 *
	 * Outputs a javascript library dblclick event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function dblclick($element = 'this', $js = '') {
		return $this->js->_dblclick ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Error
	 *
	 * Outputs a javascript library error event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function error($element = 'this', $js = '') {
		return $this->js->_error ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Focus
	 *
	 * Outputs a javascript library focus event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function focus($element = 'this', $js = '') {
		return $this->js->__add_event ( $focus, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Hover
	 *
	 * Outputs a javascript library hover event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- Javascript code for mouse over
	 * @param	string	- Javascript code for mouse out
	 * @return	string
	 */
	function hover($element = 'this', $over, $out) {
		return $this->js->__hover ( $element, $over, $out );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Keydown
	 *
	 * Outputs a javascript library keydown event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function keydown($element = 'this', $js = '') {
		return $this->js->_keydown ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Keyup
	 *
	 * Outputs a javascript library keydown event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function keyup($element = 'this', $js = '') {
		return $this->js->_keyup ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Load
	 *
	 * Outputs a javascript library load event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function load($element = 'this', $js = '') {
		return $this->js->_load ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Mousedown
	 *
	 * Outputs a javascript library mousedown event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function mousedown($element = 'this', $js = '') {
		return $this->js->_mousedown ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Mouse Out
	 *
	 * Outputs a javascript library mouseout event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function mouseout($element = 'this', $js = '') {
		return $this->js->_mouseout ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Mouse Over
	 *
	 * Outputs a javascript library mouseover event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function mouseover($element = 'this', $js = '') {
		return $this->js->_mouseover ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Mouseup
	 *
	 * Outputs a javascript library mouseup event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function mouseup($element = 'this', $js = '') {
		return $this->js->_mouseup ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Output
	 *
	 * Outputs the called javascript to the screen
	 *
	 * @access	public
	 * @param	string	The code to output
	 * @return	string
	 */
	function output($js) {
		return $this->js->_output ( $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Ready
	 *
	 * Outputs a javascript library mouseup event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function ready($js) {
		return $this->js->_document_ready ( $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Resize
	 *
	 * Outputs a javascript library resize event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function resize($element = 'this', $js = '') {
		return $this->js->_resize ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Scroll
	 *
	 * Outputs a javascript library scroll event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function scroll($element = 'this', $js = '') {
		return $this->js->_scroll ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Unload
	 *
	 * Outputs a javascript library unload event
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	string	The code to execute
	 * @return	string
	 */
	function unload($element = 'this', $js = '') {
		return $this->js->_unload ( $element, $js );
	}
	
	// --------------------------------------------------------------------
	// Effects
	// --------------------------------------------------------------------
	

	/**
	 * Add Class
	 *
	 * Outputs a javascript library addClass event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- Class to add
	 * @return	string
	 */
	function addClass($element = 'this', $class = '') {
		return $this->js->_addClass ( $element, $class );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Animate
	 *
	 * Outputs a javascript library animate event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function animate($element = 'this', $params = array(), $speed = '', $extra = '') {
		return $this->js->_animate ( $element, $params, $speed, $extra );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Fade In
	 *
	 * Outputs a javascript library hide event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function fadeIn($element = 'this', $speed = '', $callback = '') {
		return $this->js->_fadeIn ( $element, $speed, $callback );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Fade Out
	 *
	 * Outputs a javascript library hide event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function fadeOut($element = 'this', $speed = '', $callback = '') {
		return $this->js->_fadeOut ( $element, $speed, $callback );
	}
	// --------------------------------------------------------------------
	

	/**
	 * Slide Up
	 *
	 * Outputs a javascript library slideUp event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function slideUp($element = 'this', $speed = '', $callback = '') {
		return $this->js->_slideUp ( $element, $speed, $callback );
	
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Remove Class
	 *
	 * Outputs a javascript library removeClass event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- Class to add
	 * @return	string
	 */
	function removeClass($element = 'this', $class = '') {
		return $this->js->_removeClass ( $element, $class );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Slide Down
	 *
	 * Outputs a javascript library slideDown event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function slideDown($element = 'this', $speed = '', $callback = '') {
		return $this->js->_slideDown ( $element, $speed, $callback );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Slide Toggle
	 *
	 * Outputs a javascript library slideToggle event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function slideToggle($element = 'this', $speed = '', $callback = '') {
		return $this->js->_slideToggle ( $element, $speed, $callback );
	
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Hide
	 *
	 * Outputs a javascript library hide action
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function hide($element = 'this', $speed = '', $callback = '') {
		return $this->js->_hide ( $element, $speed, $callback );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Toggle
	 *
	 * Outputs a javascript library toggle event
	 *
	 * @access	public
	 * @param	string	- element
	 * @return	string
	 */
	function toggle($element = 'this') {
		return $this->js->_toggle ( $element );
	
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Toggle Class
	 *
	 * Outputs a javascript library toggle class event
	 *
	 * @access	public
	 * @param	string	- element
	 * @return	string
	 */
	function toggleClass($element = 'this', $class = '') {
		return $this->js->_toggleClass ( $element, $class );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Show
	 *
	 * Outputs a javascript library show event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function show($element = 'this', $speed = '', $callback = '') {
		return $this->js->_show ( $element, $speed, $callback );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Compile
	 *
	 * gather together all script needing to be output
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @return	string
	 */
	function compile($view_var = 'script_foot', $script_tags = TRUE) {
		$this->js->_compile ( $view_var, $script_tags );
	}
	
	/**
	 * Clear Compile
	 *
	 * Clears any previous javascript collected for output
	 *
	 * @access	public
	 * @return	void
	 */
	function clear_compile() {
		$this->js->_clear_compile ();
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * External
	 *
	 * Outputs a <script> tag with the source as an external js file
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @return	string
	 */
	function external($external_file = '', $relative = FALSE) {
		if ($external_file !== '') {
			$this->_javascript_location = $external_file;
		} else {
			if ($this->CI->config->item ( 'javascript_location' ) != '') {
				$this->_javascript_location = $this->CI->config->item ( 'javascript_location' );
			}
		}
		
		if ($relative === TRUE or strncmp ( $external_file, 'http://', 7 ) == 0 or strncmp ( $external_file, 'https://', 8 ) == 0) {
			$str = $this->_open_script ( $external_file );
		} elseif (strpos ( $this->_javascript_location, 'http://' ) !== FALSE) {
			$str = $this->_open_script ( $this->_javascript_location . $external_file );
		} else {
			$str = $this->_open_script ( $this->CI->config->slash_item ( 'base_url' ) . $this->_javascript_location . $external_file );
		}
		
		$str .= $this->_close_script ();
		return $str;
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Inline
	 *
	 * Outputs a <script> tag
	 *
	 * @access	public
	 * @param	string	The element to attach the event to
	 * @param	boolean	If a CDATA section should be added
	 * @return	string
	 */
	function inline($script, $cdata = TRUE) {
		$str = $this->_open_script ();
		$str .= ($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n";
		$str .= $this->_close_script ();
		
		return $str;
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Open Script
	 *
	 * Outputs an opening <script>
	 *
	 * @access	private
	 * @param	string
	 * @return	string
	 */
	function _open_script($src = '') {
		$str = '<script type="text/javascript" charset="' . strtolower ( $this->CI->config->item ( 'charset' ) ) . '"';
		$str .= ($src == '') ? '>' : ' src="' . $src . '">';
		return $str;
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Close Script
	 *
	 * Outputs an closing </script>
	 *
	 * @access	private
	 * @param	string
	 * @return	string
	 */
	function _close_script($extra = "\n") {
		return "</script>$extra";
	}
	
	// --------------------------------------------------------------------
	// --------------------------------------------------------------------
	// AJAX-Y STUFF - still a testbed
	// --------------------------------------------------------------------
	// --------------------------------------------------------------------
	

	/**
	 * Update
	 *
	 * Outputs a javascript library slideDown event
	 *
	 * @access	public
	 * @param	string	- element
	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
	 * @param	string	- Javascript callback function
	 * @return	string
	 */
	function update($element = 'this', $speed = '', $callback = '') {
		return $this->js->_updater ( $element, $speed, $callback );
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Generate JSON
	 *
	 * Can be passed a database result or associative array and returns a JSON formatted string
	 *
	 * @param	mixed	result set or array
	 * @param	bool	match array types (defaults to objects)
	 * @return	string	a json formatted string
	 */
	function generate_json($result = NULL, $match_array_type = FALSE) {
		// JSON data can optionally be passed to this function
		// either as a database result object or an array, or a user supplied array
		if (! is_null ( $result )) {
			if (is_object ( $result )) {
				$json_result = $result->result_array ();
			} elseif (is_array ( $result )) {
				$json_result = $result;
			} else {
				return $this->_prep_args ( $result );
			}
		} else {
			return 'null';
		}
		
		$json = array ();
		$_is_assoc = TRUE;
		
		if (! is_array ( $json_result ) and empty ( $json_result )) {
			show_error ( "Generate JSON Failed - Illegal key, value pair." );
		} elseif ($match_array_type) {
			$_is_assoc = $this->_is_associative_array ( $json_result );
		}
		
		foreach ( $json_result as $k => $v ) {
			if ($_is_assoc) {
				$json [] = $this->_prep_args ( $k, TRUE ) . ':' . $this->generate_json ( $v, $match_array_type );
			} else {
				$json [] = $this->generate_json ( $v, $match_array_type );
			}
		}
		
		$json = implode ( ',', $json );
		
		return $_is_assoc ? "{" . $json . "}" : "[" . $json . "]";
	
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Is associative array
	 *
	 * Checks for an associative array
	 *
	 * @access	public
	 * @param	type
	 * @return	type
	 */
	function _is_associative_array($arr) {
		foreach ( array_keys ( $arr ) as $key => $val ) {
			if ($key !== $val) {
				return TRUE;
			}
		}
		
		return FALSE;
	}
	
	// --------------------------------------------------------------------
	

	/**
	 * Prep Args
	 *
	 * Ensures a standard json value and escapes values
	 *
	 * @access	public
	 * @param	type
	 * @return	type
	 */
	function _prep_args($result, $is_key = FALSE) {
		if (is_null ( $result )) {
			return 'null';
		} elseif (is_bool ( $result )) {
			return ($result === TRUE) ? 'true' : 'false';
		} elseif (is_string ( $result ) or $is_key) {
			return '"' . str_replace ( array ('\\', "\t", "\n", "\r", '"', '/' ), array ('\\\\', '\\t', '\\n', "\\r", '\"', '\/' ), $result ) . '"';
		} elseif (is_scalar ( $result )) {
			return $result;
		}
	}

	// --------------------------------------------------------------------
}
// END Javascript Class

/* End of file Javascript.php */
/* Location: ./system/libraries/Javascript.php */